package com.jackson.spring.aopdemo;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.Arrays;

public class ArithmeticCalculatorLoggingProxy {

	private ArithmeticCalculator target;
	public ArithmeticCalculatorLoggingProxy(ArithmeticCalculator target) {
		this.target = target;
	}
	public ArithmeticCalculator getLoggingProxy(){
		ArithmeticCalculator proxy = null;
		//代理对象由哪个类加载器负责加载
		ClassLoader loader = target.getClass().getClassLoader();
		// 代理对象类型，及其中有哪些方法
		Class[] interfaces = new Class[]{ArithmeticCalculator.class};
		//当调用代理对象其中的方法时，
		InvocationHandler h = new InvocationHandler() {
			/**
			 * proxy:正在返回的那个代理对象，一般情况下，在invoke方法中不使用该对象
			 * method:正在被调用的方法
			 * args：调用方法时，传入的参数
			 * */
			public Object invoke(Object proxy, Method method, Object[] args)
					throws Throwable {
				String methodName = method.getName();
				System.out.println("the method "+methodName+"  begins with "+Arrays.asList(args));
				//调用目标方法
				Object result = null;
				// 前置通知，在方法执行之前执行
				try {
					result = method.invoke(target, args);
					//返回结果通知，在方法执行之后通知，
				} catch (Exception e) {
					e.printStackTrace();
					//异常通知，返回异常
				}
				// 后置通知，在方法返回之后通知，因为会出异常，所以访问不到方法的返回值
				
				
				System.out.println("the method "+methodName+"  result "+result);
				return result;
			}
		};
		proxy = (ArithmeticCalculator) Proxy.newProxyInstance(loader, interfaces, h);
		return proxy;
	}
}
